#!/bin/bash

export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8

# 项目路径和变量设置
SERVER_USER="root"
# TODO 生产环境发布的时候，只需要修改 SERVER_HOST 和 SERVER_PASSWORD
SERVER_HOST="123.57.246.18"
SERVER_PASSWORD=""

PROJECT_ROOT=$(cd "$(dirname "$0")/.." && pwd)
JAR_NAME="senlingspace-admin.jar"
SERVER_PATH="/opt/docker/app"
BACKUP_PATH="/opt/docker/app/backup"

# 日志文件路径
LOG_FILE="${PROJECT_ROOT}/scripts/deploy.log"

# 获取当前最新的镜像版本号
CURRENT_IMAGE_VERSION=$(sshpass -p "${SERVER_PASSWORD}" ssh ${SERVER_USER}@${SERVER_HOST} "docker images senlingspace-app --format '{{.Tag}}' | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+' | sort -rV | head -n 1")

# 如果当前版本为空，设置为 v2.0.0
if [ -z "$CURRENT_IMAGE_VERSION" ]; then
  CURRENT_IMAGE_VERSION="v2.0.0"
fi

log() {
  echo "$(date '+%Y-%m-%d %H:%M:%S') $1" | tee -a $LOG_FILE
}

# 递增版本号
increment_version() {
  local version=$1
  local major minor patch

  major=$(echo "$version" | cut -d '.' -f1 | tr -d 'v')
  minor=$(echo "$version" | cut -d '.' -f2)
  patch=$(echo "$version" | cut -d '.' -f3)
  patch=$((patch + 1))

  if [ "$patch" -ge 10 ]; then
    patch=0
    minor=$((minor + 1))
  fi

  echo "v${major}.${minor}.${patch}"
}

# 生成新版本号
IMAGE_NAME="senlingspace-app:$(increment_version "$CURRENT_IMAGE_VERSION")"

log "============================= prod build start ============================="
log "当前镜像版本为：${CURRENT_IMAGE_VERSION}，新镜像版本为：${IMAGE_NAME}"

# 步骤 1：检查 JAR 包是否存在
if [ ! -f "${PROJECT_ROOT}/senlingspace-admin/target/${JAR_NAME}" ]; then
  log "未找到 JAR 文件，请先构建项目。"
  exit 1
fi

log "找到 JAR 文件：${JAR_NAME}"

# 步骤 2：备份服务器上现有的 JAR 包
log "正在备份服务器上的旧 JAR 文件..."
sshpass -p "${SERVER_PASSWORD}" ssh ${SERVER_USER}@${SERVER_HOST} "mkdir -p ${BACKUP_PATH} && mv ${SERVER_PATH}/${JAR_NAME} ${BACKUP_PATH}/${JAR_NAME}_$(date +%Y%m%d%H%M%S).bak"

# 步骤 3：上传新 JAR 包至服务器
log "正在将新 JAR 文件上传到服务器..."
sshpass -p "${SERVER_PASSWORD}" rsync -avz --progress ${PROJECT_ROOT}/senlingspace-admin/target/${JAR_NAME} ${SERVER_USER}@${SERVER_HOST}:${SERVER_PATH}/
if [ $? -ne 0 ]; then
  log "上传 JAR 文件失败。"
  exit 1
fi
log "JAR 文件上传成功。"

# 步骤 4：在服务器上构建 Docker 镜像
log "正在服务器上构建 Docker 镜像..."
sshpass -p "${SERVER_PASSWORD}" ssh ${SERVER_USER}@${SERVER_HOST} "cd ${SERVER_PATH} && docker build --platform linux/amd64 -t ${IMAGE_NAME} ."
if [ $? -ne 0 ]; then
  log "Docker 构建失败。"
  exit 1
fi
log "Docker 镜像构建成功。"

# 步骤 5：停止并删除旧容器
log "正在停止并删除旧容器..."
sshpass -p "${SERVER_PASSWORD}" ssh ${SERVER_USER}@${SERVER_HOST} "docker stop senlingspace-app && docker rm senlingspace-app"
if [ $? -ne 0 ]; then
  log "停止并删除旧容器失败。"
  exit 1
fi
log "旧容器已成功停止并删除。"

# 步骤 6：启动新容器
log "正在启动新容器..."
sshpass -p "${SERVER_PASSWORD}" ssh ${SERVER_USER}@${SERVER_HOST} "docker run -d -p 8080:8080 -v /opt/logs:/apps/logs -v /home/slkj_files:/root/slkj_files -e TZ=Asia/Shanghai -e SPRING_PROFILES_ACTIVE=prod --restart=always --name senlingspace-app ${IMAGE_NAME}"
if [ $? -ne 0 ]; then
  log "启动新容器失败。"
  exit 1
fi
log "新容器已成功启动。"

# 步骤 7：检查容器日志确认启动成功并检测当前环境
log "正在检查容器日志内容以确认服务已启动并检测当前环境..."

RETRY_COUNT=0
MAX_RETRIES=10
ENVIRONMENT_DETECTED=""
ENVIRONMENT_OUTPUTTED=false

while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
  # 检查容器日志中是否包含环境信息关键字
  ENVIRONMENT_DETECTED=$(sshpass -p "${SERVER_PASSWORD}" ssh ${SERVER_USER}@${SERVER_HOST} "docker logs senlingspace-app | grep -oE 'The following [0-9]+ profile.*active: \"[a-z]+\"'")

  if [ -n "$ENVIRONMENT_DETECTED" ]; then
    # 检查标志位，确保只输出一次
    if [ "$ENVIRONMENT_OUTPUTTED" = false ]; then
      log "检测到当前运行环境：${ENVIRONMENT_DETECTED}"
      ENVIRONMENT_OUTPUTTED=true
    fi
  fi

  # 检查容器日志中是否包含启动成功的关键字
  sshpass -p "${SERVER_PASSWORD}" ssh ${SERVER_USER}@${SERVER_HOST} "docker logs senlingspace-app | grep '后端启动成功'" > /dev/null
  if [ $? -eq 0 ]; then
    log "检测到服务启动成功的日志内容。"
    break
  else
    log "服务尚未完全启动，等待 5 秒后重试..."
    sleep 5
    RETRY_COUNT=$((RETRY_COUNT + 1))
  fi
done

if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then
  log "服务启动失败，未能在日志中检测到启动成功的关键字。"
  exit 1
fi

log "部署成功完成。"
log "============================== prod build end =============================="
